package com.lingjtx.common.redis.config;

import com.alibaba.fastjson2.JSONObject;
import com.lingjtx.common.core.constant.RedisConfig;
import com.lingjtx.common.redis.topic.RedisExpiredMessage;
import com.lingjtx.common.redis.topic.RedisSubscriberMessage;
import com.lingjtx.common.thread.config.ObjectPoolTemplateConfig;
import com.lingjtx.common.thread.pooling.ObjectFactory;
import com.lingjtx.common.thread.pooling.ObjectPoolTemplate;
import jakarta.annotation.PostConstruct;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@Configuration
public class RedisConfiguration {

    private final RedisExpiredMessage redisExpiredListener;

    private final RedissonClient redissonClient;

    private final RedisSubscriberMessage redisSubscriberMessage;

    public RedisConfiguration(RedisExpiredMessage redisExpiredListener, RedissonClient redissonClient, RedisSubscriberMessage redisSubscriberMessage) {
        this.redisExpiredListener = redisExpiredListener;
        this.redissonClient = redissonClient;
        this.redisSubscriberMessage = redisSubscriberMessage;
    }

    @Bean("redisObjectPoolTemplate")
    public ObjectPoolTemplate<RedisTemplate<String, Object>> redisObjectPoolTemplate(ObjectPoolTemplateConfig config, RedisConnectionFactory redisConnectionFactory) {
        ObjectFactory<RedisTemplate<String, Object>> redisTemplateObjectFactory = new RedisTemplateFactory(redisConnectionFactory);
        return config.buildTemplate("redis", redisTemplateObjectFactory);
    }

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 配置监听过期事件
        container.addMessageListener(redisExpiredListener, new PatternTopic("__keyevent@0__:expired"));
        return container;
    }

    @PostConstruct
    public void init() {
        // 订阅 Redis 频道
        // 获取一个发布/订阅的主题（Topic）
        RTopic topic = redissonClient.getTopic(RedisConfig.REDIS_CHANNEL_ALL);

        // 订阅消息，并定义消息处理逻辑
        topic.addListener(JSONObject.class, (channel, payload) ->
                redisSubscriberMessage.handle(channel.toString(), payload));
    }
}
